﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Communication.Net.Web.JWT;
using UtilZ.Dotnet.Ex.Json;
using UtilZ.Dotnet.Ex.Log;

namespace ConAppCore
{
    internal class TestJWT
    {

        //header（头部）、payload（载荷）和signature（签名）。这三个部分在JWT里面分别对应英文句号分隔出来的三个串

        public static void Test()
        {
            string signKey = "19F75EDB_4128_463B_B11C_AAAC53EC3F80";
            Dictionary<string, string> papayloadDic = new Dictionary<string, string>();
            papayloadDic.Add(JWTHelper.JTI, $"{TimeEx.GetTimestamp()}_xx");
            papayloadDic.Add(JWTHelper.ISS, "cec");
            papayloadDic.Add(JWTHelper.AUD, "brower");
            papayloadDic.Add(JWTHelper.IAT, TimeEx.GetTimestamp().ToString());
            papayloadDic.Add("uid", "111");
            papayloadDic.Add("role", "admin");
            string jwt = JWTHelper.GenerateJwt(papayloadDic, signKey);
            JwtResult result = JWTHelper.ValidateJwt(jwt, signKey);
            if (result.Succes)
            {

            }
            else
            {

            }
        }

        private static void TestDemo()
        {
            //XXXHMACSHA256(null, null);

            var jwtHeadObj = new JWTHead() { typ = "JWT", alg = "HS256" };
            string head = JsonSerializer.SerializeObject(jwtHeadObj);

            Dictionary<string, string> papayloadDic = new Dictionary<string, string>();
            papayloadDic.Add("sub", "admin");
            papayloadDic.Add("nbf", "132465");
            papayloadDic.Add("uid", "111");
            string papayload = JsonSerializer.SerializeObject(papayloadDic);

            string secretKey = "qwe123";
            string jwtHead = Base64(head);
            string jwtPapayload = Base64(papayload);
            string jwtSign = ToHMACSHA256(secretKey, $"{jwtHead}.{jwtPapayload}");
            string jwt = $"{jwtHead}.{jwtPapayload}.{jwtSign}";

            //eyJ0cHkiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsIm5iZiI6IjEzMjQ2NSIsInVpZCI6IjExMSJ9.EM16WoAMhOcW10iarqnvmSzLTFnPYWeDeHwUWc5MwXU=

            string[] strs = jwt.Split('.');
            string headJson = Base64Decode(strs[0]);
            var jwtHeadObj2 = JsonSerializer.DeserializeObject<JWTHead>(headJson);

            string jwtSign2 = ToHMACSHA256(secretKey, $"{strs[0]}.{strs[1]}");
            if (string.Equals(jwtSign, jwtSign2, StringComparison.OrdinalIgnoreCase))
            {

            }
        }

        public static string XXXHMACSHA256(string secretKey, string text)
        {
            try
            {
                //Type[] types = typeof(HMACSHA256).Assembly.GetTypes();
                //Type rsaType = typeof(RSA);
                //Type ecdsaType = typeof(ECDsa);
                //Type hmacType = typeof(HMAC);

                //List<Type> rsaTypeList = new List<Type>();
                //List<Type> ecdsaTypeList = new List<Type>();
                //List<Type> hmacTypeList = new List<Type>();

                //foreach (Type type in types)
                //{
                //    if (!type.IsClass)
                //    {
                //        continue;
                //    }

                //    if (type.IsSubclassOf(type))
                //    {
                //        rsaTypeList.Add(type);
                //    }
                //    else if (type.IsSubclassOf(type))
                //    {
                //        ecdsaTypeList.Add(type);
                //    }
                //    else if (type.IsSubclassOf(hmacType))
                //    {
                //        hmacTypeList.Add(type);
                //    }
                //}

                //using var rsa256 = RSA.Create("SHA256");
                //using var rsa384 = RSA.Create("SHA384");
                //using var rsa512 = RSA.Create("SHA512");

                //using var escd256 = ECDsa.Create("SHA256");
                //using var escd384 = ECDsa.Create("SHA384");
                //using var escd512 = ECDsa.Create("SHA512");

                //using var hs256 = HMACSHA256.Create("SHA256");
                //using var hs384 = HMACSHA384.Create("SHA384");
                //using var hs512 = HMACSHA512.Create("SHA512");

                //RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                //ECDsaCng.Create

                //RSASSASHA256
                //HMACSHA256.

                using var hs256 = HMACSHA256.Create("SHA256");
                hs256.Key = Encoding.UTF8.GetBytes(secretKey);
                byte[] hash = hs256.ComputeHash(Encoding.UTF8.GetBytes(text));
                string xx = Convert.ToBase64String(hash);

                using (HMACSHA256 mac = new HMACSHA256())
                {

                }
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }

            return "";
        }


        public static string ToHMACSHA256(string secretKey, string text)
        {
            using var hs256 = new HMACSHA256();
            hs256.Key = Encoding.UTF8.GetBytes(secretKey);
            byte[] hash = hs256.ComputeHash(Encoding.UTF8.GetBytes(text));
            return Convert.ToBase64String(hash);
        }

        public static string Base64(string text)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(text);
            string jwtStr = Convert.ToBase64String(buffer);
            return jwtStr.Replace('+', '-').Replace('/', '_').TrimEnd('=');
        }

        public static string Base64Decode(string base64Text)
        {
            string jwtStr = base64Text.Replace('-', '+').Replace('_', '/');
            int mod = jwtStr.Length % 4;
            if (mod == 2)
            {
                jwtStr += "==";
            }
            else if (mod == 3)
            {
                jwtStr += "=";
            }

            byte[] buffer = Convert.FromBase64String(jwtStr);
            return Encoding.UTF8.GetString(buffer);
        }
    }

    public class JWTPapayload
    {
        //        iss(Issuser)：代表这个JWT的签发主体； 
        //sub(Subject)：代表这个JWT的主体，即它的所有人； 
        //aud(Audience)：代表这个JWT的接收对象； 
        //exp(Expiration time)：是一个时间戳，代表这个JWT的过期时间； 
        //nbf(Not Before)：是一个时间戳，代表这个JWT生效的开始时间，意味着在这个时间之前验证JWT是会失败的； 
        //iat(Issued at)：是一个时间戳，代表这个JWT的签发时间； 
        //jti(JWT ID)：是JWT的唯一标识。
    }

    public class JWTHead
    {
        public string typ { get; set; } = "JWT";

        public string alg { get; set; } = "HS256";


        public JWTHead()
        {

        }
    }

    public enum JWTAlgs
    {
        /// <summary>
        /// HMAC SHA-256 hash algorithm
        /// </summary>
        HS256,

        /// <summary>
        /// HMAC SHA-384 hash algorithm
        /// </summary>
        HS384,

        /// <summary>
        /// HMAC SHA-512 hash algorithm
        /// </summary>
        HS512,



        /// <summary>
        /// RSASSA SHA-256 hash algorithm
        /// </summary>
        RS256,

        /// <summary>
        /// RSASSA SHA-384 hash algorithm
        /// </summary>
        RS384,

        /// <summary>
        /// RSASSA SHA-512 hash algorithm
        /// </summary>
        RS512,




        /// <summary>
        /// ECDSA P-256 curve and SHA-256 hash algorithm
        /// </summary>
        ES256,

        /// <summary>
        /// ECDSA P-384 curve and SHA-384 hash algorithm
        /// </summary>
        ES384,

        /// <summary>
        /// ECDSA P-512 curve and SHA-512 hash algorithm
        /// </summary>
        ES512,




        /// <summary>
        /// 无数字签名
        /// </summary>
        NONE
    }
}
